package com.song.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
import java.io.UnsupportedEncodingException;

public class EmailUtils {

    private static final Logger logger = LoggerFactory.getLogger(EmailUtils.class);

    /**
     * 获得邮件主题
     * @param msg 邮件内容
     * @return 解码后的邮件主题
     */
    public static String getSubject(MimeMessage msg) throws UnsupportedEncodingException, MessagingException {
        String subject = msg.getHeader("Subject", null);
        String subjectToUpperCase = subject.toUpperCase();
        if (subjectToUpperCase != null
                && (subjectToUpperCase.startsWith(CommonConstant.UTF_8_B) || (subjectToUpperCase.startsWith(CommonConstant.UTF_8_Q)))
                && subjectToUpperCase.endsWith(CommonConstant.UTF_8_END)) {
            return decodeUtf8Text(subject);
        } else {
            return msg.getSubject() == null ? "" : msg.getSubject();
        }
    }

    /**
     * 文本解码
     *
     * @param encodeText    解码MimeUtility.encodeText(String text)方法编码后的文本
     * @return 解码后的文本
     * @throws UnsupportedEncodingException
     */
    public String decodeText(String encodeText) throws UnsupportedEncodingException {
        String encodeTextUpperCase = encodeText.toUpperCase();

        if (encodeText == null || "".equals(encodeText)) {
            return "";
        } else {
            if ((encodeTextUpperCase.startsWith(CommonConstant.UTF_8_B) || encodeTextUpperCase.startsWith(CommonConstant.UTF_8_Q)) && encodeTextUpperCase.endsWith(CommonConstant.UTF_8_END)) {
                return decodeUtf8Text(encodeText);
            } else {
                String decodeText = "";
                if (encodeText.startsWith("=??B?") && encodeText.endsWith("?=")) {
                    encodeText = encodeText.replaceAll("=\\?\\?B\\?", "=\\?gb2312\\?B\\?");
                }
                try {
                    decodeText = MimeUtility.decodeText(encodeText);
                } catch (UnsupportedEncodingException e) {
                    logger.error(e.getMessage(), e);
                }
                return decodeText;
            }
        }
    }


    /**
     * 如果接收到的是utf-8的数据，提前处理，否则会有乱码
     * base64加密字符串是将字符串转换为字节数组(byte[])，其中每3个字节(8比特)转换为 4个(6比特)进行编码。
     * 我们知道一个中文字符占2个字节，当2个中文字符转换为base64时就会出现用“=”等号补位的情况。
     * 附件名前缀"=?UTF-8?B?"其中UTF-8 表示使用utf-8编码，B 表示base64编码，附件名结尾固定为 "?="。
     *
     * 第一种情况：
     * 如果出现补位情況就是"=?="，javax.mail.internet.MimeUtility.decodeText(String)在解析的時候碰到=?=就会忽略后面的字符只解析前面的字符。
     * 这就是造成文件名不完整的原因。
     *
     * 第二种情况：
     * 一个中文字符有可能被拆成两块，decodeText(String) 解析的时候就无法组成一个正确的中文字符，所以产生乱码。
     *
     * 这个方法用来处理这两种情况，以保证decodeText(String)能够正确解析。
     */
    public static String decodeUtf8Text(String etext) {

        String etextUpperCase = etext.toUpperCase();
        String decodeText = "";

        int index = 0;

        Integer post = etext.indexOf("?=");
        if (post != (etext.length() - 2)) {
            if (etextUpperCase.startsWith(CommonConstant.UTF_8_B) && etextUpperCase.endsWith(CommonConstant.UTF_8_END)) {

                while (etext.indexOf(CommonConstant.UTF_8_END, index + 1) != etext.lastIndexOf(CommonConstant.UTF_8_END)) {

                    String e = etext.substring(index, etext.indexOf(CommonConstant.UTF_8_END, index + 1));// 判断前一位是否是 base64“=”补位
                    index = etext.indexOf(CommonConstant.UTF_8_END, index + 1);
                    if (e.endsWith("=")) {// 有等号
                        continue;
                    } else {
                        if( (etextUpperCase.lastIndexOf(CommonConstant.UTF_8_B) != -1) && (etextUpperCase.lastIndexOf(CommonConstant.UTF_8_Q) != -1)  ) {
//							=?utf-8?B?5L2Z6aKd5oql6KGoX+S7t+WAvOi/nOetljHlj7coMjAxOS0wOC0wOOiHszIw?= =?utf-8?Q?19-08-08).xls?=
//							这种情况极少出现如果碰到就暂不加工字符串。可以得到正确的解密字符串。实际上我们最好将每种加密的方式取出单独解密 然后在拼接在一起。
                        }else {
                            String end = etext.substring(index, etext.length());
                            end = end.substring((end.toUpperCase().indexOf(CommonConstant.UTF_8_B) + 9), end.length());
                            etext = etext.substring(0, index) + end;
                        }
                    }
                }
            } else if (etextUpperCase.startsWith(CommonConstant.UTF_8_Q) && etextUpperCase.endsWith(CommonConstant.UTF_8_END)) {

//				Integer postQ = etext.toUpperCase().indexOf(UTF_8_Q, 9);
//				etext = etext.substring(0, post) + etext.substring(postQ + 10, (etext.length()));

                String[] s = etext.split("=[?](.*?)(?i)UTF-8[?](.*?)(?i)Q[?]");
                etext = CommonConstant.UTF_8_Q;
                for(int i = 0; i < s.length; i ++) {
                    String ss = s[i].trim();
                    if(ss.lastIndexOf("?=") != -1) {
                        etext += ss.substring(0, ss.length() -2);
                    }
                }
                etext += CommonConstant.UTF_8_END;
            }
        }
        try {
            decodeText = MimeUtility.decodeText(etext);
        } catch (UnsupportedEncodingException e) {
            logger.error(e.getMessage(), e);
        }
        return decodeText;
    }

}
